package cs342.group1.messenger;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;

import com.example.grouponemessenger.R;
import com.example.grouponemessenger.R.layout;
import com.example.grouponemessenger.R.menu;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private Database db; 
	private ListView conversationList;
	private ListAdapter conversationAdapter;
	private int cloudId;
	private AlertDialog.Builder dlgAlert;
	public static Context mainContext;
	private boolean active = false;
	private boolean lastProcessDone = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		System.out.println("CREATED!!!!!!!!!!!!!!!!!!!!!!!");
		setContentView(R.layout.activity_main);
		mainContext = this;
		dlgAlert  = new AlertDialog.Builder(this);
		conversationList = (ListView)findViewById(R.id.conversations_list);
		conversationList.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
			{
				Contact clickedContact = (Contact) conversationAdapter.getItem(position);
				Toast.makeText(mainContext, clickedContact.toString(), Toast.LENGTH_LONG).show();
				Intent intent = new Intent(mainContext, Conversation.class);
				int userId = clickedContact.getFromID();
				intent.putExtra("userId", userId);
				startActivity(intent);
			}
			
		});
		
		db = new Database(this);
	}
	
	Runnable periodicTask = new Runnable () {
	    @Override
	    public void run () {
	    	new TimeoutRequests().execute();
	    }
	};
	
	public void NewConversation(View v){
		Intent loginIntent = new Intent(MainActivity.this,NewConversation.class);
    	startActivity(loginIntent);
	}
	
	/*
	 * This method will be called once the database has checked if a user is logged in.
	 * If no user is logged in, null will be returned and we want to redirect the user to the 
	 * login page. Otherwise we will want to pull the users messages to this device.
	 */
	public void ProcessUserLoggedIn(User user){
		if(user == null){
			//redirect to login page here
			Intent loginIntent = new Intent(MainActivity.this,Login.class);
	    	startActivity(loginIntent);
		}
		else{
			//pull user messages here
			cloudId = user.CloudId;
			
			TextView greeting = (TextView)findViewById(R.id.greeting);
			greeting.setText(user.Username +  "'s Conversations");
			Conversation.staticID = user.CloudId;
			
			Message[] messages;
			GetAllMessagesForUser task = new GetAllMessagesForUser();
			task.execute(user.CloudId);
			try {
				messages = task.get();
				
			}
			catch (Exception e) {
				messages = new Message[0];
			}
			PutMessagesInDatabase task2 = new PutMessagesInDatabase();
			task2.execute(messages);
			try {
				//messages are now in android database, we can query and list names of conversations from here
				if(task2.get()){
					new InitializeConversationList().execute();
				}
			}
			catch (Exception e) {
				//error, display error or just log the user out
				System.out.print(e);
				//Intent loginIntent = new Intent(MainActivity.this,Login.class);
		    	//startActivity(loginIntent);
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch(item.getItemId())
		{
		case R.id.action_logout:
			db.open();
			db.LogOutUser();
			db.close();
			Intent loginIntent = new Intent(MainActivity.this,Login.class);
	    	startActivity(loginIntent);
			return true;
		case R.id.mainToSaved:
			Intent savedIntent = new Intent(MainActivity.this,SavedMessages.class);
	    	startActivity(savedIntent);
		default:
			return true;
		}
	}
	
	public class InitializeConversationList extends AsyncTask<Object, Object, Object>
	{

		@Override
		protected Object doInBackground(Object... arg0) {
			db.open();
			ArrayList<Contact> conversationsWith = db.getUniqueFromContacts();
			ArrayList<Contact> nonMyself = new ArrayList<Contact>();
			ArrayList<Contact> nonDup = new ArrayList<Contact>();
			for(Contact con : conversationsWith){
				if(con.getFromID() == cloudId){
					//already in list, do not put in
				}else{
					nonMyself.add(con);
				}
			}
			for(Contact con : nonMyself){
				boolean alreadyIn = false;
				for(Contact con2 : nonDup){
					if(con2.getName().equals(con.getName())){
						//already in do not add
						alreadyIn = true;
					}
				}
				if(!alreadyIn){
					nonDup.add(con);
				}
			}
			return nonDup;
		}
		
		@Override
		protected void onPostExecute(Object result)
		{
			conversationAdapter = new ArrayAdapter<Contact>(mainContext,R.layout.conversation_list_item,R.id.conversation_name,(ArrayList<Contact>)result);
			conversationList.setAdapter(conversationAdapter);
			new java.util.Timer().schedule( 
			        new java.util.TimerTask() {
			            @Override
			            public void run() {
			            	new TimeoutRequests().execute();
			            }
			        }, 
			        15000 
			);
			lastProcessDone = true;
		}
		
		
	}
	
	public class CheckUserLoggedIn extends AsyncTask<Void, Void, User> {
		// perform the database access
		User user;
		
		@Override
		protected User doInBackground(Void... params) {
			db.open();
			// call database and return user, if null, no user logged in
			user = db.CheckUserLoggedIn();
			return user;
		} // end method doInBackground
		
		@Override
		protected void onPostExecute(User user)
		{
			ProcessUserLoggedIn(user);
		} // end method onPostExecute

	}
	
	public class GetAllMessagesForUser extends AsyncTask<Integer, Void, Message[]> {
		@Override
		protected Message[] doInBackground(Integer... params) {
			
			return new CloudHelper().GetAllMessagesForUser(params[0]);
		}
	}
	
	public class PutMessagesInDatabase extends AsyncTask<Message[], Void, Boolean> {
		@Override
		protected Boolean doInBackground(Message[]... params) {
			db.open();
			db.DeleteAllMessages();
			for(Message m : params[0]){
				db.open();
				db.insertMessage(m);
			}
			return true;
		}
	}
	
	public class TimeoutRequests extends AsyncTask<Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... params) {
			int androidCount = -1;
			int cloudCount = -1;
			try {
				db.open();
				androidCount = db.GetMessageCount();
			}
			catch (Exception e) {
				
			}
			try {
				cloudCount = new CloudHelper().GetMessageCount(cloudId);
				
			}
			catch (Exception e) {
				
			}
			
			if(cloudCount < 0|| androidCount < 0){
				
			}
			else if(cloudCount > androidCount && active && lastProcessDone){
				//display message for new messages
				int difference = cloudCount - androidCount;
				lastProcessDone = false;
				dlgAlert.setMessage("You have " + difference + " new message" + (difference > 1 ? "s" : ""));
				dlgAlert.setTitle("New Message");
				dlgAlert.setPositiveButton("Ok",
					    new DialogInterface.OnClickListener() {
					        public void onClick(DialogInterface dialog, int which) {
					          //dismiss the dialog  
					        	new CheckUserLoggedIn().execute();
					        	new java.util.Timer().schedule( 
								        new java.util.TimerTask() {
								            @Override
								            public void run() {
								            	new TimeoutRequests().execute();
								            }
								        }, 
								        15000 
								);
					        }
					    });
				dlgAlert.setCancelable(true);
				MainActivity.this.runOnUiThread(new Runnable() {

			        public void run() {
			        	try{
			        		dlgAlert.create().show();
			        	}
			        	catch(Exception e){
			        		//something happened with the dialog, oh well
			        	}

			        }
			    });
			}
			else{
				new java.util.Timer().schedule( 
				        new java.util.TimerTask() {
				            @Override
				            public void run() {
				            	new TimeoutRequests().execute();
				            }
				        }, 
				        15000 
				);
			}
			
			return null;
		}
	}
	
	@Override
	public void onPause() {
	    super.onPause();  // Always call the superclass method first
	    active = false;
	}
	
	@Override
	public void onResume() {
		/// see if any user is logged in, the perform an action in the ProcessUserLoggedIn method
	    super.onResume();  // Always call the superclass method first
	    active = true;
	    new CheckUserLoggedIn().execute();
	}
}
